# CMakeList.txt: learn-cpp 的 CMake 项目，包括源和定义
# 此处特定于项目的逻辑。
#
cmake_minimum_required (VERSION 3.8)

# TODO: 如有需要，请添加测试并安装目标。

#set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")

if(NOT DEFINED ENV{VCPKG_ROOT})
	message(FATAL_ERROR "Define ENV{VCPKG_ROOT} first!!!")
endif()

if(UNIX AND NOT APPLE)
	set(VCPKG_TARGET_TRIPLET "x64-linux" CACHE STRING "")
elseif(MSVC)
	set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "")
endif()

#message(VCPKG_TARGET_TRIPLET=[${VCPKG_TARGET_TRIPLET}])

if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
	set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
endif()

#message(CMAKE_TOOLCHAIN_FILE=[${CMAKE_TOOLCHAIN_FILE}])

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")

set (PROJECT_NAME "learn-cpp")

project (${PROJECT_NAME})

if(UNIX AND NOT APPLE)

	include_directories($ENV{VCPKG_ROOT}/installed/x64-linux/include)
	link_directories($ENV{VCPKG_ROOT}/installed/x64-linux/lib)

	#set(THREADS_PREFER_PTHREAD_FLAG ON)
	#find_package(Threads REQUIRED)

	# find_library(boost CONFIG REQUIRED)
	# find_package(gflags CONFIG REQUIRED)
	# find_package(glog CONFIG REQUIRED)
	find_package(folly CONFIG REQUIRED)
	find_package(wangle CONFIG REQUIRED)
	# find_library(libuv CONFIG REQUIRED)
	find_package(CURL CONFIG REQUIRED)
	find_package(uvw CONFIG REQUIRED)
	find_package(CAF CONFIG REQUIRED)

endif()

set (PROJECT_ROOT_PATH ${CMAKE_SOURCE_DIR})

file(GLOB NGGS_SRCS "${PROJECT_ROOT_PATH}/nggs/*.cpp"
				    "${PROJECT_ROOT_PATH}/nggs/*.h"
)

add_library(nggs STATIC ${NGGS_SRCS})

target_include_directories(nggs PUBLIC ${PROJECT_ROOT_PATH})

set(LESSONS lesson1
			lesson2
			lesson3
			lesson4
			lesson5
			lesson6
			lesson7
			lesson8
			lesson9
			lesson10
			lesson11
			lesson12
			lesson13
			lesson14
			lesson15
			lesson16
)

set(TESTS test1
		  test2
		  test3
		  test4
		  test5
		  test6
		  test7
		  test8
		  test9
		  test10
)

set(BENCHMARKS benchmark1
)

set(CONCURRENCYINACTION cia.1.1
)

set(PROJECTS ${LESSONS}
			 ${TESTS}
			 ${BENCHMARKS}
			 ${CONCURRENCYINACTION}
)

#foreach(P ${PROJECTS})
#endforeach()

foreach(P ${LESSONS})
	file(GLOB SRCS "${PROJECT_ROOT_PATH}/lesson/${P}/*.cpp"
	               "${PROJECT_ROOT_PATH}/lesson/${P}/*.c"
				   "${PROJECT_ROOT_PATH}/lesson/${P}/*.h"
				   "${PROJECT_ROOT_PATH}/lesson/${P}/*.hpp"
	)

	if(${P} STREQUAL "lesson9")

		file(GLOB DETAIL_SRCS "${PROJECT_ROOT_PATH}/lesson/${P}/detail/*.cpp"
							  "${PROJECT_ROOT_PATH}/lesson/${P}/detail/*.c"
							  "${PROJECT_ROOT_PATH}/lesson/${P}/detail/*.h"
							  "${PROJECT_ROOT_PATH}/lesson/${P}/detail/*.hpp"
		)

		add_executable(${P} ${SRCS} ${DETAIL_SRCS})

		source_group("detail" FILES ${DETAIL_SRCS})

	else()

		add_executable(${P} ${SRCS})

	endif()

	set_target_properties(${P} PROPERTIES
		FOLDER "lesson"
		CXX_STANDARD 17
		CXX_STANDARD_REQUIRED ON
		CXX_EXTENSIONS ON
	)

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH})

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH}/lesson/${P})

	target_link_libraries(${P} nggs)

	if(MSVC)

		set_target_properties("${P}" PROPERTIES VS_GLOBAL_VcpkgEnabled true)

		add_compile_options("/Zc:__cplusplus")

	endif()

	if(${P} STREQUAL "lesson2")

		if(MSVC)

			#add_definitions(-D_DISABLE_EXTENDED_ALIGNED_STORAGE)
			add_definitions(-D_HAS_STD_BYTE=0)

			target_link_libraries(${P} ws2_32 Iphlpapi)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} fizz folly)
			target_link_libraries(${P} gflags glog)
			target_link_libraries(${P} dl pthread)
			target_link_libraries(${P} boost_context boost_program_options boost_thread boost_filesystem boost_system boost_chrono)
			target_link_libraries(${P} ssl crypto z event double-conversion sodium fmt)

		else()

		endif()

	elseif(${P} STREQUAL "lesson3")

		if(MSVC)

			add_definitions(/D_SILENCE_CXX17_IS_LITERAL_TYPE_DEPRECATION_WARNING)

		endif()

	elseif(${P} STREQUAL "lesson7" OR ${P} STREQUAL "lesson8")

		if(MSVC)

			#add_definitions(-D_DISABLE_EXTENDED_ALIGNED_STORAGE)
			#add_definitions(/D_HAS_STD_BYTE=0)

			target_link_libraries(${P} ws2_32 Iphlpapi)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} wangle fizz folly)
			target_link_libraries(${P} gflags glog)
			target_link_libraries(${P} dl pthread)
			target_link_libraries(${P} boost_context boost_program_options boost_thread boost_filesystem boost_system boost_chrono)
			target_link_libraries(${P} ssl crypto z event double-conversion sodium fmt)

		else()
		endif()

	elseif(${P} STREQUAL "lesson9")

		if(MSVC)

			#add_definitions(-D_WIN32_WINNT=0x0601)
			#add_definitions(/bigobj)

			#target_link_libraries(${P} boost_context boost_fiber)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} pthread boost_context boost_fiber)

		else()
		endif()

	elseif(${P} STREQUAL "lesson10")

		if(MSVC)

			add_definitions(-D_WIN32_WINNT=0x0601)
			add_definitions(/bigobj)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} pthread)

		else()

		endif()

		
	elseif(${P} STREQUAL "lesson11")

		if(MSVC)

			target_link_libraries(${P} ${CURL_LIBRARY} CAF)
			target_link_libraries(${P} ssl)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} ${CURL_LIBRARY} CAF::io CAF::internal)
			target_link_libraries(${P} ssl crypto z dl pthread)

		else()

	endif()

	elseif(${P} STREQUAL "lesson13")

		if(MSVC)

			#add_definitions(-D_DISABLE_EXTENDED_ALIGNED_STORAGE)
			#add_definitions(/D_HAS_STD_BYTE=0)

			target_link_libraries(${P} uv ws2_32 Iphlpapi)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} uv_a dl pthread)

		else()

		endif()
	
	elseif(${P} STREQUAL "lesson14")

		if(MSVC)

			add_definitions(-D_CRT_SECURE_NO_WARNINGS)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} ${CURL_LIBRARY} uv_a ssl crypto z dl pthread)

		else()

		endif()

	elseif(${P} STREQUAL "lesson15")
		if(MSVC)

		elseif(UNIX AND NOT APPLE)

			target_link_libraries(${P} pthread boost_thread)

		endif()

	else()

	endif()

endforeach()

foreach(P ${TESTS})
	file(GLOB SRCS "${PROJECT_ROOT_PATH}/test/${P}/*.cpp"
				   "${PROJECT_ROOT_PATH}/test/${P}/*.h"
				   "${PROJECT_ROOT_PATH}/test/${P}/*.hpp"
	)

	add_executable(${P} ${SRCS})

	set_target_properties(${P} PROPERTIES
		FOLDER "test"
		CXX_STANDARD 17
		CXX_STANDARD_REQUIRED ON
		CXX_EXTENSIONS ON
	)

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH})

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH}/test/${P})

	target_link_libraries(${P} nggs)

	if(MSVC)

		set_target_properties("${P}" PROPERTIES VS_GLOBAL_VcpkgEnabled true)

		add_compile_options("/Zc:__cplusplus")

	endif()

endforeach()

foreach(P ${BENCHMARKS})
	file(GLOB SRCS "${PROJECT_ROOT_PATH}/benchmark/${P}/*.cpp"
				   "${PROJECT_ROOT_PATH}/benchmark/${P}/*.h"
				   "${PROJECT_ROOT_PATH}/benchmark/${P}/*.hpp"
	)

	add_executable(${P} ${SRCS})

	set_target_properties(${P} PROPERTIES
		FOLDER "benchmark"
		CXX_STANDARD 17
		CXX_STANDARD_REQUIRED ON
		CXX_EXTENSIONS ON
	)

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH})

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH}/benchmark/${P})

	target_link_libraries(${P} nggs)

	if(MSVC)

		set_target_properties("${P}" PROPERTIES VS_GLOBAL_VcpkgEnabled true)

		add_compile_options("/Zc:__cplusplus")

	endif()

endforeach()

foreach(P ${CONCURRENCYINACTION})
	file(GLOB SRCS "${PROJECT_ROOT_PATH}/concurrency_in_action/${P}/*.cpp"
				   "${PROJECT_ROOT_PATH}/concurrency_in_action/${P}/*.h"
				   "${PROJECT_ROOT_PATH}/concurrency_in_action/${P}/*.hpp"
	)

	add_executable(${P} ${SRCS})

	set_target_properties(${P} PROPERTIES
		FOLDER "concurrency_in_action"
		CXX_STANDARD 17
		CXX_STANDARD_REQUIRED ON
		CXX_EXTENSIONS ON
	)

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH})

	target_include_directories(${P} PUBLIC ${PROJECT_ROOT_PATH}/concurrency_in_action/${P})

	target_link_libraries(${P} nggs)

	if(MSVC)

		set_target_properties("${P}" PROPERTIES VS_GLOBAL_VcpkgEnabled true)

		add_compile_options("/Zc:__cplusplus")

	endif()

endforeach()
